﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Media;
using System.Data;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Net;

namespace EmaEditor
{
    public static class ControlValidator
    {
        public static bool EnsureGreaterThan(this TextBox txt, TextBox otherbox, CancelEventArgs e, ErrorProvider ep)
        {
            int lowval, hival;

            // Only perform this test if both are filled in
            if (int.TryParse(txt.Text, out hival) && int.TryParse(otherbox.Text, out lowval)) {
                if (hival < lowval) {
                    if (e != null) e.Cancel = true;
                    ep.SetError(txt, "High value must be above lower value");
                    txt.Focus();
                    txt.JumpToParentTab();
                    return false;
                }
            }

            // All is well
            return true;
        }

        public static bool EnsureValidFQDN(this TextBox txt, CancelEventArgs e, ErrorProvider ep)
        {
            string pattern = @"(?=^.{1,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{1,})$)";
            Match m = Regex.Match(txt.Text, pattern);

            // If we fail a basic match, error out
            if (m.Success) {

                // Turn into a domain name
                string[] cells = txt.Text.Split('.');
                StringBuilder hostname = new StringBuilder();
                for (int i = cells.Length - 1; i >= 0; i--) {
                    hostname.Append(cells[i]);
                    hostname.Append(".");
                }
                hostname.Length -= 1;

                // Lookup
                try {
                    IPAddress[] addresslist = Dns.GetHostAddresses(hostname.ToString());
                    if (addresslist.Length > 0) {
                        return true;
                    }

                // DNS lookup failure
                } catch (Exception ex) {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    return false;
                }
            }

            // No success
            e.Cancel = true;
            ep.SetError(txt, "Please enter a valid fully qualified domain name (FQDN).");
            return false;
        }

        public static bool EnsureFieldNotEmpty(this TextBox txtbox, CancelEventArgs e, ErrorProvider ep)
        {
            return EnsureFieldNotEmpty(txtbox, "Field cannot be blank", e, ep);
        }
        public static bool EnsureFieldNotEmpty(this TextBox txtbox, string errorMsg, CancelEventArgs e, ErrorProvider ep, bool swapto)
        {

            if (txtbox.Text.Trim().Length == 0)
            {
                if (e != null) e.Cancel = true;
                ep.SetError(txtbox, errorMsg);
                if (swapto == true)
                {
                    txtbox.Focus();
                    txtbox.JumpToParentTab();
                }
                return false;
            }
            return true;
        }
        public static bool EnsureFieldNotEmpty(this TextBox txtbox, string errorMsg, CancelEventArgs e, ErrorProvider ep)
        {
            return EnsureFieldNotEmpty(txtbox, errorMsg, e, ep, true);

            //if (txtbox.Text.Trim().Length == 0) {
            //    if (e != null) e.Cancel = true;
            //    ep.SetError(txtbox, errorMsg);
            //   txtbox.Focus();
            //   txtbox.JumpToParentTab();
            //    return false;
            //} 
            //return true;
        }

        public static bool EnsureNumIsValid(this TextBox txtbox, CancelEventArgs e, ErrorProvider ep)
        {
            return EnsureNumIsValid(txtbox, typeof(int), e, ep);
        }

        public static bool EnsureNumIsValid(this TextBox txtbox, Type numeric_type, CancelEventArgs e, ErrorProvider ep)
        {
            if (txtbox.Enabled == true) {

                // If we can successfully convert to the selected numeric type, we're fine
                try {
                    Convert.ChangeType(txtbox.Text.Trim(), numeric_type);

                } catch {
                    if (e != null) e.Cancel = true;
                    ep.SetError(txtbox, "Not a number");
                    txtbox.JumpToParentTab();
                    txtbox.Focus();
                    return false;
                }
            }

            // All is well
            return true;
        }

        public static bool EnsureDropListSelected(this ComboBox cbx, CancelEventArgs e, ErrorProvider ep)
        {
            if (cbx.SelectedIndex == 0) {
                ep.SetError(cbx, "Please pick an item from the list");
                if (e != null) e.Cancel = true;
                cbx.Focus();
                cbx.JumpToParentTab();
                return false;
            } else {
                return true;
            }
        }

        public static TabPage GetParentTabPage(this Control c)
        {
            Control parent = c.Parent;
            if (parent is TabPage) {
                return parent as TabPage;
            } else if (parent != null) {
                return GetParentTabPage(parent);
            }

            // Failed to get parent
            return null;
        }

        public static void JumpToParentTab(this Control c)
        {
            TabPage tp = GetParentTabPage(c);
            if (tp != null) {
                TabControl tab = tp.Parent as TabControl;
                tab.SelectedTab = tp;
            }
        }
    }
}
